package com.jixi.service.impl;

import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jixi.common.result.PageResult;
import com.jixi.common.result.Result;
import com.jixi.mapper.CompanyMapper;
import com.jixi.mapper.OrderDailyMapper;
import com.jixi.mapper.SchoolMapper;
import com.jixi.mapper.SetmealMapper;
import com.jixi.pojo.entity.Company;
import com.jixi.pojo.entity.OrderDaily;
import com.jixi.pojo.entity.School;
import com.jixi.pojo.entity.Setmeal;
import com.jixi.pojo.vo.OrderDailyListVO;
import com.jixi.pojo.vo.OrderSetMealTotalDownloadVo;
import com.jixi.pojo.vo.companyMealVO;
import com.jixi.service.OrderDailyService;
import jakarta.servlet.http.HttpServletResponse;
import org.burningwave.core.assembler.StaticComponentContainer;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.net.URLEncoder;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class OrderDailyServiceImpl extends ServiceImpl<OrderDailyMapper, OrderDaily> implements OrderDailyService {
	
	@Autowired
	private OrderDailyMapper orderDailyMapper;
	
	@Autowired
	private SetmealMapper setmealMapper;
	
	@Autowired
	private SchoolMapper schoolMapper;
	
	@Autowired
	private CompanyMapper companyMapper;
	
	/**
	 * 日订餐订单列表
	 *
	 * @param pageNum         页码
	 * @param pageSize        每页数量
	 * @param orderNumber     订单编号
	 * @param schoolId        学校id
	 * @param companyId       餐饮公司id
	 * @param orderDateStatus 订单状态
	 * @param timeValue       时间（天）
	 * @return 日订餐订单列表
	 */
	@Override
	public Result<PageResult> orderDailyPage(
			Integer pageNum,
			Integer pageSize,
			String orderNumber,
			Long schoolId,
			Long companyId,
			Integer orderDateStatus,
			String timeValue
	) {
		//分页构造器
		Page<OrderDaily> pageInfo = new Page<>(pageNum, pageSize);
		
		//条件构造器
		LambdaQueryWrapper<OrderDaily> queryWrapper = new LambdaQueryWrapper<>();
		//只查未删除的
		queryWrapper.eq(OrderDaily::getIsDeleted, 0);
		//添加可能有的过滤条件
		queryWrapper.like(orderNumber != null && ! orderNumber.trim().isEmpty(), OrderDaily::getOrderNumber, orderNumber);
		queryWrapper.eq(schoolId != null, OrderDaily::getSchoolId, schoolId);
		queryWrapper.eq(companyId != null, OrderDaily::getCompanyId, companyId);
		queryWrapper.eq(orderDateStatus != null, OrderDaily::getOrderDateStatus, orderDateStatus);
		queryWrapper.eq(timeValue != null && ! timeValue.trim().isEmpty(), OrderDaily::getOrderDate, timeValue);
		//优先按照订单编号降序排序，其次按照订单日期降序排序
		queryWrapper.orderByDesc(OrderDaily::getOrderNumber, OrderDaily::getOrderDate);
		
		//执行分页查询
		orderDailyMapper.selectPage(pageInfo, queryWrapper);
		
		//处理名字信息
		List<OrderDailyListVO> orderDailyList = pageInfo.getRecords().stream()
				.map(orderDaily -> {
					OrderDailyListVO vo = new OrderDailyListVO();
					BeanUtils.copyProperties(orderDaily, vo); //使用Spring的Bean工具类复制属性
					
					Long setmealId1 = vo.getSetmealId();
					Setmeal setmeal = setmealMapper.selectById(setmealId1);
					if (setmeal == null || setmeal.getIsDeleted() == 1) {
						vo.setSetmealName("该套餐不存在");
					} else if (setmeal.getStatus() == 0) {
						vo.setSetmealName(setmeal.getSetmealName() + "（该套餐已停售）");
					} else {
						vo.setSetmealName(setmeal.getSetmealName());
					}
					
					Long schoolId1 = vo.getSchoolId();
					School school = schoolMapper.selectById(schoolId1);
					if (school == null || school.getIsDeleted() == 1) {
						vo.setSchoolName("该学校不存在");
					} else if (school.getStatus() == 0) {
						vo.setSchoolName(school.getSchoolName() + "（该学校已停用）");
					} else {
						vo.setSchoolName(school.getSchoolName());
					}
					
					Long companyId1 = vo.getCompanyId();
					Company company = companyMapper.selectById(companyId1);
					if (company == null || company.getIsDeleted() == 1) {
						vo.setCompanyName("该餐饮公司不存在");
					} else if (company.getStatus() == 0) {
						vo.setCompanyName(company.getCompanyName() + "（该餐饮公司已停用）");
					} else {
						vo.setCompanyName(company.getCompanyName());
					}
					
					return vo;
				}).collect(Collectors.toList());
		
		//处理分页信息
		PageResult pageResult = new PageResult(pageInfo.getTotal(), orderDailyList);
		return Result.success(pageResult);
	}
	
	/**
	 * 通过id查日订餐订单详情
	 *
	 * @param orderDateId 日订餐订单id
	 * @return 日订餐订单详情
	 */
	@Override
	public OrderDaily getOrderDailyInfoById(Long orderDateId) {
		//只查未删除的
		LambdaQueryWrapper<OrderDaily> queryWrapper = new LambdaQueryWrapper<>();
		queryWrapper.eq(OrderDaily::getIsDeleted, 0);
		queryWrapper.eq(OrderDaily::getOrderDateId, orderDateId);
		OrderDaily orderDaily = orderDailyMapper.selectOne(queryWrapper);
		return orderDaily;
	}
	
	/**
	 * 通过订单编号查日订餐订单详情
	 *
	 * @param orderNumber 订单编号
	 * @return 日订餐订单详情
	 */
	@Override
	public OrderDaily getOrderDailyInfoByNumber(String orderNumber) {
		//只查未删除的
		LambdaQueryWrapper<OrderDaily> queryWrapper = new LambdaQueryWrapper<>();
		queryWrapper.eq(OrderDaily::getIsDeleted, 0);
		queryWrapper.eq(OrderDaily::getOrderNumber, orderNumber);
		OrderDaily orderDaily = orderDailyMapper.selectOne(queryWrapper);
		return orderDaily;
	}
	
	/**
	 * 统计日订餐订单数量
	 *
	 * @return 日订餐订单数量
	 */
	@Override
	public Long countDailyOrder() {
		LambdaQueryWrapper<OrderDaily> queryWrapper = new LambdaQueryWrapper<>();
		queryWrapper.eq(OrderDaily::getIsDeleted, 0);
		return orderDailyMapper.selectCount(queryWrapper);
	}
	
	/**
	 * 查询套餐的已完成订单数量和总金额
	 * <!>
	 * 该接口可能会废弃
	 * <!>
	 *
	 * @param setmealId 套餐id
	 * @return 查询结果
	 */
	@Override
	public Result<Map<String, Object>> selectsetmealumAndMoney(Long setmealId) {
		//只查未删除的
		LambdaQueryWrapper<OrderDaily> queryWrapper = new LambdaQueryWrapper<>();
		queryWrapper.eq(OrderDaily::getIsDeleted, 0);
		queryWrapper.eq(OrderDaily::getSetmealId, setmealId);
		//只查已完成的订单的套餐
		queryWrapper.eq(OrderDaily::getOrderDateStatus, 1);
		
		Long count = orderDailyMapper.selectCount(queryWrapper);
		Double totalMoney = count * orderDailyMapper.selectById(setmealId).getAmount();
		
		Map<String, Object> map = new HashMap<>();
		map.put("count", count);
		map.put("totalMoney", totalMoney);
		
		return Result.success(map);
	}
	
	/**
	 * 查询公司与学校相关联的套餐的订单总数量和总金额
	 *
	 * @param companyId 公司id
	 * @param schoolId  学校id
	 * @param timeValue 时间（天）
	 * @return 查询结果
	 */
	@Override
	public Result<Map<String, Object>> selectCountCompanySchoolSetmeal(Long companyId, Long schoolId, String timeValue) {
		//查询（时间区间可选）
		LambdaQueryWrapper<OrderDaily> queryWrapper = new LambdaQueryWrapper<>();
		queryWrapper.eq(OrderDaily::getIsDeleted, 0);
		queryWrapper.eq(OrderDaily::getCompanyId, companyId);
		queryWrapper.eq(OrderDaily::getSchoolId, schoolId);
		queryWrapper.eq(timeValue != null && ! timeValue.trim().isEmpty(), OrderDaily::getOrderDate, timeValue);
		
		List<OrderDaily> orderDailyList = orderDailyMapper.selectList(queryWrapper);
		Long totalSetmealNum = 0L;
		Double totalMoney = 0.0;
		
		//枚举日订单表，统计数据
		for (OrderDaily orderDaily : orderDailyList) {
			totalSetmealNum++;
			totalMoney += orderDaily.getAmount();
		}
		
		Map<String, Object> resultMap = new HashMap<>();
		resultMap.put("totalSetmealNum", totalSetmealNum);
		resultMap.put("totalMoney", totalMoney);
		
		return Result.success(resultMap);
	}
	
	/**
	 * 统计各餐饮公司各学校按月的出餐统计信息
	 *
	 * @param pageNum   页码
	 * @param pageSize  每页数量
	 * @param companyId 餐饮公司id
	 * @param schoolId  学校id
	 * @param timeValue 时间（月）
	 * @param status    状态（注意，status值为2时需映射2、3、4一起查询）
	 * @return 各餐饮公司各学校按天的出餐统计信息
	 */
	@Override
	public Result<PageResult> CompanyMealOrderPage(
			Integer pageNum,
			Integer pageSize,
			Long companyId,
			Long schoolId,
			String timeValue,
			Integer status
	) {
		/*
		由于需要进行数据处理，为了避免出现本页数据条数与pageSize不一致情况，
		先对数据进行处理，然后再进行分页配置。
		 */
		
		// 条件构造器
		LambdaQueryWrapper<OrderDaily> queryWrapper = new LambdaQueryWrapper<>();
		
		//查询条件
		//只查未删除的
		queryWrapper.eq(OrderDaily::getIsDeleted, 0);
		queryWrapper.eq(companyId != null, OrderDaily::getCompanyId, companyId);
		queryWrapper.eq(schoolId != null, OrderDaily::getSchoolId, schoolId);
		queryWrapper.like(timeValue != null && ! timeValue.trim().isEmpty(), OrderDaily::getOrderDate, timeValue);
		if (status != null) {
			// 如果status为2，则使用in方法添加多个可能的状态（2、3、4）
			if (status == 2) {
				queryWrapper.in(OrderDaily::getOrderDateStatus, Arrays.asList(2, 3, 4));
			} else {
				// 否则，仅等于给定的status
				queryWrapper.eq(OrderDaily::getOrderDateStatus, status);
			}
		}
		
		//执行分页查询，将查询结果保存到List
		List<OrderDaily> orderDailyList = orderDailyMapper.selectList(queryWrapper);
		
		//枚举处理符合查询条件的订单
		Map<String, companyMealVO> map = new HashMap<>();
		for (OrderDaily orderDaily : orderDailyList) {
			
			//对于特殊配餐，没有绑定的餐饮公司，不进行统计
			if(orderDaily.getCompanyId() == null || orderDaily.getSchoolId() == null){
				continue;
			}
			
			//将订单日期去掉日
			DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
			String orderDateStr = orderDaily.getOrderDate().format(formatter);
			String targetOrderDateString = orderDateStr.substring(0, 7);  //截取前7个字符，即 "yyyy-MM"
			
			//处理状态值，如果status为2、3、4，则统一设置为2
			Integer orderStatusTemp = orderDaily.getOrderDateStatus();
			if (orderStatusTemp == 2 || orderStatusTemp == 3 || orderStatusTemp == 4) {
				orderStatusTemp = 2;
			}
			
			//通过map统计数据
			String key = orderDaily.getCompanyId() + "-" + orderDaily.getSchoolId() + "-" + orderStatusTemp + "-" + targetOrderDateString;
			companyMealVO vo = map.get(key);
			if (vo == null) {
				vo = new companyMealVO();
				vo.setCompanyId(orderDaily.getCompanyId());
				
				//处理名字
				Company company = companyMapper.selectById(orderDaily.getCompanyId());
				if (company == null || company.getIsDeleted() == 1) {
					vo.setCompanyName("该餐饮公司不存在");
				} else if (company.getStatus() == 0) {
					vo.setCompanyName(company.getCompanyName() + "（该餐饮公司已停用）");
				} else {
					vo.setCompanyName(company.getCompanyName());
				}
				
				vo.setSchoolId(orderDaily.getSchoolId());
				
				//处理名字
				School school = schoolMapper.selectById(orderDaily.getSchoolId());
				if (school == null || school.getIsDeleted() == 1) {
					vo.setSchoolName("该学校不存在");
				} else if (school.getStatus() == 0) {
					vo.setSchoolName(school.getSchoolName() + "（该学校已停用）");
				} else {
					vo.setSchoolName(school.getSchoolName());
				}
				
				vo.setTimeValue(targetOrderDateString);
				vo.setStatus(orderStatusTemp);
				vo.setTotalSetmealNum(0L);
				vo.setTotalMoney(0D);
				map.put(key, vo);
			}
			//更新套餐数量和总金额
			vo.setTotalSetmealNum(vo.getTotalSetmealNum() + 1);
			vo.setTotalMoney(vo.getTotalMoney() + orderDaily.getAmount());
		}
		
		//将Map中的值转成List
		List<companyMealVO> companyMealVOList = new ArrayList<>(map.values());
		
		//先对 companyMealVOList 按照 timeValue 属性降序排序，再按照 companyId 降序排序，最后按照 schoolId 降序排序
		companyMealVOList.sort(
				Comparator.comparing(companyMealVO::getTimeValue, Comparator.reverseOrder())
						.thenComparing(companyMealVO::getCompanyId, Comparator.reverseOrder())
						.thenComparing(companyMealVO::getSchoolId, Comparator.reverseOrder())
		);
		
		//配置分页信息
		Page<companyMealVO> pageInfo = new Page<>(pageNum, pageSize);
		
		//设置总记录数
		long totalRecords = companyMealVOList.size();
		pageInfo.setTotal(totalRecords);
		
		//计算起始索引和结束索引
		int fromIndex = (int) Math.min((int) (pageInfo.getCurrent() - 1) * pageInfo.getSize(), (int) totalRecords);
		int toIndex = (int) Math.min((int) fromIndex + pageInfo.getSize(), (int) totalRecords);
		
		//分页截取当前页的数据
		List<companyMealVO> pageList = companyMealVOList.subList(fromIndex, toIndex);
		pageInfo.setRecords(pageList);
		
		PageResult resultPage = new PageResult(pageInfo.getTotal(), pageInfo.getRecords());
		
		return Result.success(resultPage);
	}
	
	/**
	 * 导出3，出餐情况统计统计excel
	 */
	@Override
	public void downloadCompanyMealOrderPage(HttpServletResponse response, String timeValue) throws IOException {
		//执行查询
		List<OrderSetMealTotalDownloadVo> list = setmealMapper.getOrderSetMealTotalDownload(timeValue);
		System.out.println(list);
		//excel下载
		StaticComponentContainer.Modules.exportAllToAll();
		response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
		response.setCharacterEncoding("utf-8");
		String fileName = URLEncoder.encode("订单情况按月统计（" + timeValue + ")", "UTF-8").replaceAll("\\+", "%20");
		response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
		EasyExcel.write(response.getOutputStream(), OrderSetMealTotalDownloadVo.class)
				.sheet("订单情况按月统计（" + timeValue + ")")
				.doWrite(list);
	}
}

